import re
import io
import os
import subprocess

# 示例文本内容 (替换为您的文件路径或实际内容)
file_content = """
795 个结果 - 540 文件

build_tools/output/repo/acado-vendor/CMakeLists.txt:
  16  include(ExternalProject)
  17
  18  externalproject_add(acado-1.2.2-cho3
  19:   GIT_REPOSITORY https://github.com/cho3/acado.git
  20    GIT_TAG 8366e22cd5d815078e8d24f78dbced28b48d7e32
  21    GIT_SHALLOW 1
  22    TIMEOUT 600

  31    DESTINATION ${CMAKE_INSTALL_PREFIX})
  32
  33  externalproject_add(hpmpc-cho3
  34:   GIT_REPOSITORY https://github.com/cho3/hpmpc.git
  35    GIT_TAG abbcf0806e4c8763ab2129a90efd827d194c1b00
  36    GIT_SHALLOW 1
  37    TIMEOUT 600

build_tools/output/repo/andino-base/CMakeLists.txt:
  11  find_package(pluginlib REQUIRED)
  12
  13  # libserial:
  14: # Following linking instructions from: https://github.com/crayzeewulf/libserial/blob/master/examples/example_project/CMakeLists.txt
  15  set(THREADS_HAVE_PTHREAD_ARG 1)
  16  find_package(Threads REQUIRED)
  17
  18  # Include libserial for serial communication
  19  # Typical find_package() does not work for libserial, for reference see:
  20: # https://github.com/crayzeewulf/libserial/issues/113#issuecomment-432245159
  21  find_package(PkgConfig)
  22  pkg_check_modules(SERIAL libserial)
  23

build_tools/output/repo/as2-behaviors-trajectory-generation/generate_polynomial_trajectory_behavior/CMakeLists.txt:
  10    include(FetchContent)
  11    fetchcontent_declare(
  12      dynamic_trajectory_generator
  13:     GIT_REPOSITORY https://github.com/miferco97/dynamic_trajectory_generator.git
  14      GIT_TAG master
  15    )
  16    fetchcontent_makeavailable(dynamic_trajectory_generator)

build_tools/output/repo/behaviortree-cpp-v3/CMakeLists.txt:
  106          include(FetchContent)
  107          FetchContent_Declare(
  108              googletest
  109:             URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
  110              )
  111          # For Windows: Prevent overriding the parent project's compiler/linker settings
  112          set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

build_tools/output/repo/console-bridge-vendor/CMakeLists.txt:
   71
   72    # Download and build console_bridge
   73    externalproject_add(console_bridge-1.0.2
   74:     URL https://github.com/ros/console_bridge/archive/1.0.2.tar.gz
   75      URL_HASH SHA256=303a619c01a9e14a3c82eb9762b8a428ef5311a6d46353872ab9a904358be4a4
   76      TIMEOUT 600
   77      CMAKE_ARGS

build_tools/output/repo/depthai-examples/CMakeLists.txt:
  39
  40  set(deeplab_blob "${PROJECT_SOURCE_DIR}/resources/${deeplab_blob_name}")
  41  file(DOWNLOAD
  42: "https://github.com/luxonis/depthai-experiments/blob/master/gen2-deeplabv3_multiclass/models/deeplab_v3_plus_mnv2_decoder_256_openvino_2021.4.blob?raw=true"
  43    ${deeplab_blob}
  44    TIMEOUT 60  # seconds
  45    EXPECTED_HASH SHA1=bdc2529f765f34c4799b478690fb4e32f1ad5d89

build_tools/output/repo/fields2cover/CMakeLists.txt:
  112    message("Or-tools not found -- Downloading and building from source")
  113
  114    FetchContent_Declare(ortools FETCHCONTENT_UPDATES_DISCONNECTED
  115:     URL https://github.com/google/or-tools/releases/download/v9.9/or-tools_amd64_ubuntu-22.04_cpp_v9.9.3963.tar.gz
  116    )
  117    FetchContent_Populate(ortools)
  118    include_directories(${ortools_SOURCE_DIR}/include)
"""

# 正则表达式
git_repo_pattern = re.compile(r"GIT_REPOSITORY\s+(https://github\.com/[^\s]+)", re.IGNORECASE)
git_tag_pattern = re.compile(r"GIT_TAG\s+([^\s]+)", re.IGNORECASE)
url_pattern = re.compile(r"(https://github\.com/.*?\.(?:zip|gz))\b", re.IGNORECASE)

DOWNLOAD_DIR = "downloads"
IS_DBG = False

def create_download_directory():
    """创建下载目录"""
    if not os.path.exists(DOWNLOAD_DIR):
        os.makedirs(DOWNLOAD_DIR)
        print(f"创建下载目录: {DOWNLOAD_DIR}")

def download_repo(repo_info, target_dir):
    """使用 git clone 下载仓库"""
    repo_url = repo_info['repo']
    tag = repo_info['tag']
    repo_name = repo_url.split('/')[-1].replace('.git', '')
    clone_path = os.path.join(target_dir, repo_name)

    if os.path.exists(clone_path):
        print(f"目录已存在，跳过仓库: {repo_name}")
        return

    print(f"开始下载仓库: {repo_url} 到 {clone_path}")
    cmd = ['git', 'clone']
    if tag:
        cmd.extend(['--branch', tag, '--depth', '1'])
    cmd.extend([repo_url, clone_path])

    try:
        # 设置 GIT_HTTP_VERSION 环境变量为 1.1
        env = os.environ.copy()
        env['GIT_HTTP_VERSION'] = 'HTTP/1.1'
        subprocess.run(cmd, check=True, capture_output=True, text=True, env=env)
        print(f"成功下载仓库: {repo_name}")
    except subprocess.CalledProcessError as e:
        print_error(f"下载仓库失败: {repo_url}", e)
    except FileNotFoundError:
        print("错误: 'git' 命令未找到。请确保已安装 Git。")
    except Exception as e:
        print_error(f"下载仓库时发生未知错误: {repo_url}", e)

def download_archive(url, target_dir):
    """使用 curl 下载归档文件"""
    # 清理 URL，去除多余的空格和换行符
    cleaned_url = url.strip()
    print(f"开始处理文件: {cleaned_url}")
    file_name = cleaned_url.split('/')[-1]

    if 'archive' in cleaned_url:
        archive_index = cleaned_url.index('archive')
        parts_before_archive = cleaned_url[:archive_index].split('/')
        if len(parts_before_archive) >= 2:
            package_name = parts_before_archive[-2]
        else:
            package_name = file_name.split('.')[0] if '.' in file_name else file_name
    else:
        package_name = file_name.split('.')[0] if '.' in file_name else file_name

    package_dir = os.path.join(target_dir, package_name)

    if not os.path.exists(package_dir):
        os.makedirs(package_dir)

    output_path = os.path.join(package_dir, file_name)

    if os.path.exists(output_path):
        print(f"文件 {file_name} 已存在，跳过下载。")
        return

    print(f"开始下载文件: {cleaned_url} 到 {output_path}")
    # 添加 --insecure 选项
    cmd = ['curl', '-o', output_path, '-L', '--insecure', cleaned_url]

    try:
        subprocess.run(cmd, check=True, capture_output=True, text=True)
        print(f"成功下载文件: {file_name}")
    except subprocess.CalledProcessError as e:
        print_error(f"下载文件失败: {cleaned_url}", e)
    except FileNotFoundError:
        print("错误: 'curl' 命令未找到。请确保已安装 curl。")
    except Exception as e:
        print_error(f"下载文件时发生未知错误: {cleaned_url}", e)

def print_error(message, error):
    """统一错误处理函数"""
    print(message)
    if hasattr(error, 'stderr'):
        print(f"错误信息: {error.stderr}")
    else:
        print(f"错误信息: {error}")

def read_file_lines(file_path):
    """读取文件内容"""
    try:
        if IS_DBG:
            return io.StringIO(file_content).readlines()
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.readlines()
    except FileNotFoundError:
        print(f"Error: File not found at {file_path}")
        return []
    except Exception as e:
        print(f"An error occurred: {e}")
        return []

def extract_repositories_and_urls(lines):
    """提取仓库和 URL 信息"""
    repositories = []
    urls = []
    i = 0
    while i < len(lines):
        line = lines[i].strip()
        repo_match = git_repo_pattern.search(line)
        if repo_match:
            repo_url = repo_match.group(1)
            tag = None
            if i + 1 < len(lines):
                next_line = lines[i + 1].strip()
                tag_match = git_tag_pattern.search(next_line)
                if tag_match:
                    tag = tag_match.group(1)
                    i += 1
            repositories.append({"repo": repo_url, "tag": tag})
        elif not line.startswith("#"):
            url_match = url_pattern.search(line)
            if url_match:
                urls.append(url_match.group(1))
        i += 1
    return repositories, urls

def remove_duplicates(repositories, urls):
    """去重处理"""
    unique_urls = list(set(urls))
    unique_repositories = []
    seen_repos = set()
    for item in repositories:
        repo_url = item['repo']
        if repo_url not in seen_repos:
            unique_repositories.append(item)
            seen_repos.add(repo_url)
    return unique_repositories, unique_urls

def print_and_save_results(repositories, urls):
    """打印结果并保存到文件"""
    print("--- Repositories and Tags ---")
    for item in repositories:
        print(f"Repository: {item['repo']}, Tag: {item['tag']}")

    print("\n--- Archive URLs ---")
    for url in urls:
        print(f"URL: {url}")

    repo_output_file = "repositories_list.txt"
    url_output_file = "urls_list.txt"

    try:
        print(f"\n将仓库信息写入文件: {repo_output_file}")
        with open(repo_output_file, 'w', encoding='utf-8') as f_repo:
            for item in repositories:
                tag_info = f", Tag: {item['tag']}" if item['tag'] else ""
                f_repo.write(f"Repository: {item['repo']}{tag_info}\n")

        print(f"将 URL 信息写入文件: {url_output_file}")
        with open(url_output_file, 'w', encoding='utf-8') as f_url:
            for url in urls:
                f_url.write(f"{url}\n")
        print("文件写入完成。")
    except Exception as e:
        print_error("写入文件时出错", e)

def read_repositories_from_file(file_path):
    """从 repositories_list.txt 文件中读取仓库信息"""
    repositories = []
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            for line in f:
                if line.startswith("Repository:"):
                    parts = line.split(', Tag:')
                    repo_url = parts[0].replace("Repository: ", "").strip()
                    tag = parts[1].strip() if len(parts) > 1 else None
                    repositories.append({"repo": repo_url, "tag": tag})
    except FileNotFoundError:
        print(f"Error: File not found at {file_path}")
    except Exception as e:
        print(f"An error occurred while reading {file_path}: {e}")
    return repositories


def download_repositories_from_file(file_path, target_dir):
    # 从 repositories_list.txt 读取仓库信息
    repo_file_path = "repositories_list.txt"
    repositories_from_file = read_repositories_from_file(repo_file_path)
    if repositories_from_file:
        print("\n从 repositories_list.txt 读取到新的仓库信息，开始下载...")
        for item in repositories_from_file:
            download_repo(item, DOWNLOAD_DIR)


def gen_download_file():
    file_path = 'github_pkg.txt'
    create_download_directory()
    lines = read_file_lines(file_path)
    if not lines:
        print("未找到有效的文件内容，退出程序。")
        return

    repositories, urls = extract_repositories_and_urls(lines)
    unique_repositories, unique_urls = remove_duplicates(repositories, urls)
    print_and_save_results(unique_repositories, unique_urls)



    # print("\n--- 开始下载 ---")
    # print(f"\n下载 Git 仓库到 '{DOWNLOAD_DIR}' 目录...")
    # for item in unique_repositories:
    #     download_repo(item, DOWNLOAD_DIR)



def download_from_urls():
    url_file_path = "urls_list.txt"
    # 检查文件是否存在
    if not os.path.exists(url_file_path):
        print(f"错误: 文件 {url_file_path} 不存在，请先运行 gen_download_file 函数生成。")
        return
    
    urls_from_file = read_file_lines(url_file_path)
    if not urls_from_file:
        print(f"错误: 从 {url_file_path} 中未读取到有效的 URL 信息。")
        return
    
    print(f"\n下载归档文件到 '{DOWNLOAD_DIR}' 目录...")
    for url in urls_from_file:
        url = url.strip()  # 去除行尾的换行符
        if url:
            download_archive(url, DOWNLOAD_DIR)

    print("\n--- 下载完成 ---")

def download_from_repo_file():
    repo_file_path = "repositories_list.txt"
    repositories_from_file = read_repositories_from_file(repo_file_path)
    if repositories_from_file:
        print("\n从 repositories_list.txt 读取到新的仓库信息，开始下载...")
        for item in repositories_from_file:
            download_repo(item, DOWNLOAD_DIR)
    else:
        print("未从 repositories_list.txt 读取到有效的仓库信息。")


if __name__ == "__main__":
    # main()
    # download_from_urls()
    download_from_repo_file()
